/*
* @(#)ListDmsFolderSelectAction.java
*
* Copyright (c) 2003 DCIVision Ltd
* All rights reserved.
*
* This software is the confidential and proprietary information of DCIVision
* Ltd ("Confidential Information").  You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with DCIVision Ltd.
*/
package com.dcivision.dms.web;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.dcivision.audit.bean.AuditTrail;
import com.dcivision.audit.dao.AuditTrailDAObject;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsRoot;
import com.dcivision.dms.core.DocumentRetrievalManager;
import com.dcivision.dms.core.DocumentValidateManager;
import com.dcivision.dms.core.RootOperationManager;
import com.dcivision.dms.core.RootRetrievalManager;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.dms.dao.DmsRootDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.web.AbstractListAction;
import com.dcivision.framework.web.AbstractSearchForm;

/**
 * <p>Class Name:       ListDmsFolderSelectAction.java    </p>
 * <p>Description:      The list action class for ListDmsFolderSelect.jsp</p>
 *
 *    @author           Zoe Shum
 *    @company          DCIVision Limited
 *    @creation date    27/02/2004
 *    @version          $Revision: 1.38.2.4 $
 */

public class ListDmsFolderSelectAction extends AbstractListAction {

  public static final String REVISION = "$Revision: 1.38.2.4 $";


  /**
   *  Constructor - Creates a new instance of ListArchiveAction and define the default listName.
   */
  public ListDmsFolderSelectAction() {
    super();
    this.setListName("dmsFolderSelectList");
  }

  /**
   * getMajorDAOClassName
   *
   * @return  The class name of the major DAObject will be used in this action.
   */
  public String getMajorDAOClassName() {
    return("com.dcivision.dms.dao.DmsDocumentDAObject");
  }

  /**
   * getFunctionCode
   *
   * @return  The corresponding system function code of action.
   */
  public String getFunctionCode() {
    return(SystemFunctionConstant.DMS_PUBLIC_FOLDER);
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    if (sessionContainer.getPermissionManager().hasAccessRight(SystemFunctionConstant.DMS_PERSONAL_FOLDER, "R")) {
      this.functionCode = SystemFunctionConstant.DMS_PERSONAL_FOLDER;
    } else {
      this.functionCode = SystemFunctionConstant.DMS_PUBLIC_FOLDER;
    }
    return(super.execute(mapping, form, request, response));
  }
  
  public List getDocList(AbstractSearchForm form, HttpServletRequest request) throws ApplicationException {
  	List docList = new ArrayList();
  	ListDmsFolderSelectForm docForm = (ListDmsFolderSelectForm)form;
  	Connection conn = this.getConnection(request);
  	SessionContainer sessionContainer = this.getSessionContainer(request);
  	PermissionManager pm = sessionContainer.getPermissionManager();
  	
  	DocumentRetrievalManager docRetrieval = new DocumentRetrievalManager(sessionContainer,conn);
  	DmsDocumentDAObject documentDAO = new DmsDocumentDAObject(sessionContainer,conn);
  	DmsRootDAObject dmsRootDAO = new DmsRootDAObject(sessionContainer,conn);
//    List tmpDocList = documentDAO.getFullList(docForm);
    
    AuditTrailDAObject auditTrailDAO=new AuditTrailDAObject(sessionContainer,conn);
    List tmpDocList = auditTrailDAO.getListByDocumentType(docForm);
    
    if (tmpDocList != null){
     	for (int i=0;tmpDocList.size()>i;i++){
    		AuditTrail auditTrail = (AuditTrail)tmpDocList.get(i);
    		Integer docID = auditTrail.getObjectID();
    		DmsDocument dmsDoc = (DmsDocument)documentDAO.getObjectByID(docID);
    		
    		if (DmsDocument.DOCUMENT_LINK.equals(dmsDoc.getDocumentType())){    			
    			DmsDocument tmpDoc = docRetrieval.getRelationshipTargetDocument(dmsDoc.getID(),DmsDocument.DOCUMENT_LINK);
    			if (tmpDoc == null) continue;
    			DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(tmpDoc.getRootID());  
    			
      		if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,tmpDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
      			docList.add(auditTrail);
      		} 
    		} else {
    			DmsRoot dmsRoot = (DmsRoot)dmsRootDAO.getObjectByID(dmsDoc.getRootID());
      		if (pm.hasAccessRight(conn,GlobalConstant.OBJECT_TYPE_DOCUMENT,dmsDoc.getID(),"R") || dmsRoot.getOwnerID().equals(this.getSessionContainer(request).getUserRecordID())){
      			docList.add(auditTrail);
      		}
    		} 		      
    	}
    }
    
  	return docList;
  }
  
  public List getPageList(AbstractSearchForm form, HttpServletRequest request) throws ApplicationException {

  	ListDmsFolderSelectForm docForm = (ListDmsFolderSelectForm)form;
  	List result = new ArrayList();
  	int pageSize = TextUtility.parseInteger(docForm.getPageOffset());
  	
  	while (result.size() < pageSize){
			List tmpList = this.getDocList(docForm,request);
			if (tmpList == null || tmpList.size() < 1) break; 
			for (int k = 0; tmpList.size() > k; k++){
				if (result.size() >= pageSize) break;
				result.add(tmpList.get(k));
	  }
			docForm.setCurStartRowNo(TextUtility.parseInteger(docForm.getCurStartRowNo()) + pageSize + "");
		}
  	return result;
  }
  
  public String getCurPageCursor(String cursor,int CurPageNo){
  	String curCursor = "1";
  	if (Utility.isEmpty(cursor)) return curCursor;
  	StringTokenizer cursorToken = new StringTokenizer(cursor,";");
  	
  	while (cursorToken.hasMoreTokens()){
  		String tmpCursor = cursorToken.nextToken();
  		if (tmpCursor.indexOf(CurPageNo + "-") != -1){
  			StringTokenizer tmpToken = new StringTokenizer(tmpCursor,"-");
  			tmpToken.nextToken();
  			curCursor  = tmpToken.nextToken();
  		}
  	}
  	return curCursor;
  }
  
  public List getAccessListData(AbstractSearchForm form, HttpServletRequest request) throws ApplicationException {
  	ListDmsFolderSelectForm docSearchForm = (ListDmsFolderSelectForm)form;
  	Integer pageAmountInc = SystemParameterFactory.getSystemParameterInteger(SystemParameterConstant.DMS_LIST_PAGEAMOUNT);
		List result = new ArrayList();
		int pageSize = TextUtility.parseInteger(docSearchForm.getPageOffset());
		int curPageNo = TextUtility.parseInteger(docSearchForm.getCurPageNO());
		int lastPageNo = TextUtility.parseInteger(docSearchForm.getLastPageNO());
		int pageAmount = TextUtility.parseInteger(docSearchForm.getPageAmount());	
		
		StringBuffer cursor = null;
		if (docSearchForm.getCursor() != null){
			cursor = new StringBuffer(docSearchForm.getCursor());
		} else {
			cursor = new StringBuffer();
		}
		
		if (curPageNo == 0 || curPageNo == 1){
			curPageNo = 0;
			cursor.delete(0,cursor.length());
		}
		
		//get list Date
		String startRowNo = this.getCurPageCursor(cursor.toString(),curPageNo);
		docSearchForm.setCurStartRowNo(startRowNo);
		result = this.getPageList(docSearchForm,request);
		
		//get cursor
		List cursorList = new ArrayList();
		AuditTrail tmpDoc = null;
		
		if (curPageNo == lastPageNo || curPageNo == 0){
			//page = 1
			if (!(result.size() < pageSize)){
				//set start page cursor
  			tmpDoc = (AuditTrail)result.get(pageSize-1);
  			if (tmpDoc != null){
  				docSearchForm.setCurStartRowNo(tmpDoc.getRowNum()+1 + "");
  			}
  			
  			int loopTimes = 0;
  			if (curPageNo == 0){
  				loopTimes = 1;
  				lastPageNo = 1;
  				int j = 1;
  			}
  			
  			for (;loopTimes<pageAmountInc.intValue(); loopTimes++){
  				cursorList = this.getPageList(docSearchForm,request);
  				
  				if (!Utility.isEmpty(cursorList)){
  					tmpDoc = (AuditTrail)cursorList.get(0);
  					++lastPageNo;
  					pageAmount = lastPageNo;
  					cursor.append(lastPageNo);
  					cursor.append("-");
  					cursor.append(tmpDoc.getRowNum());
  					cursor.append(";");     				
    				
  					if (!(cursorList.size() < pageSize)){
  						tmpDoc = (AuditTrail)cursorList.get(pageSize-1);
    					if (tmpDoc == null)break;
    					docSearchForm.setCurStartRowNo(tmpDoc.getRowNum()+1 + "");
  					} else {
  						lastPageNo = -1;
  						break;
  					}
  					
  				} else {
  					lastPageNo = -1;
  				}    				
    		} 
  			
  			if (lastPageNo != -1 && lastPageNo == curPageNo + pageAmountInc.intValue()){
  				cursorList = this.getPageList(docSearchForm,request);
  				if (Utility.isEmpty(cursorList)) lastPageNo = -1;
  			}
  			
  		}       			
		}
		
		if (curPageNo == 0) curPageNo = 1;
		docSearchForm.setCursor(cursor.toString());
		docSearchForm.setPageAmount(pageAmount + "");
		docSearchForm.setCurPageNO(curPageNo + "");
		docSearchForm.setLastPageNO(lastPageNo + "");
		docSearchForm.setPageAmount(pageAmount + "");
//		request.setAttribute(this.m_sListName,result);
		return result;
  }
  
  public void getListData(ActionMapping mapping, AbstractSearchForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection conn = this.getConnection(request);
    ListDmsFolderSelectForm docSearchForm = (ListDmsFolderSelectForm) form;
    DocumentRetrievalManager docRetrievalManager = null;
    RootOperationManager rootOperationManager = null;
    RootRetrievalManager rootRetrievalManager = null;
    DocumentValidateManager docValidateManager = null;
    DmsDocument documentRoot = null;
    List folderTreeList = new ArrayList();
    String path = "";
    String allowCompoundDoc = docSearchForm.getAllowCompoundDoc();
    String allowPaperDoc = docSearchForm.getAllowPaperDoc();
    String sMaintMtmDocumentRelationshipForm = "maintMtmDocumentRelationshipForm";
    String allowPersonalOnly = request.getParameter("allowPersonalOnly");
    String allowPublicOnly = request.getParameter("allowPublicOnly");

    try {
      // Retrieve the accessible public root list.
      docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
      rootOperationManager = new RootOperationManager(sessionContainer, conn);
      rootRetrievalManager = new RootRetrievalManager(sessionContainer, conn);
      
      List publicRootList = new ArrayList();
      
      //for personal doc can not bind with workflow. 
      if("false".equals(docSearchForm.getAllowPersonalDoc())){
        publicRootList = rootRetrievalManager.getAccessiblePublicRootsList();
      }else{
        DmsRoot rootForRootLit = rootRetrievalManager.getRootObject(TextUtility.parseIntegerObj(docSearchForm.getRootID()));
        /*
        if((sMaintMtmDocumentRelationshipForm.equals(docSearchForm.getFormName()) && DmsRoot.PERSONAL_ROOT.equals(rootForRootLit.getRootType()))
            || ( !Utility.isEmpty(allowPersonalOnly) && "true".equals(allowPersonalOnly))){
          publicRootList = rootRetrievalManager.getAccessiblePersonalRootsList();
        }else if (!Utility.isEmpty(allowPublicOnly) && "true".equals(allowPublicOnly)){
          publicRootList = rootRetrievalManager.getAccessiblePublicRootsList();
        } else {
          publicRootList = rootRetrievalManager.getAllAccessibleRootsList();
        }
        */
        
        if (!Utility.isEmpty(allowPersonalOnly) && "true".equals(allowPersonalOnly)){
          if (!Utility.isEmpty(allowPublicOnly) && "true".equals(allowPublicOnly)){
            publicRootList = rootRetrievalManager.getAllAccessibleRootsList();
          } else {
            publicRootList = rootRetrievalManager.getAccessiblePersonalRootsList();
          }
        } else if (!Utility.isEmpty(allowPublicOnly) && "true".equals(allowPublicOnly)){
          publicRootList = rootRetrievalManager.getAccessiblePublicRootsList();
        } else {
          publicRootList = rootRetrievalManager.getAllAccessibleRootsList();
        }
        //publicRootList = rootRetrievalManager.getAllAccessibleRootsList();
      }
      request.setAttribute("publicRootList", publicRootList);
      DmsDocument docTep = null;
      String myFavoriteName = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_MYFAVORITE_FOLDER_NAME);
      String sortAttribute = docSearchForm.getSortAttribute();
      String sortOrder = docSearchForm.getSortOrder();
      
      if ("M".equals(docSearchForm.getActionType()) || "P".equals(docSearchForm.getActionType())){
        docTep = docRetrievalManager.getMyFavoriteObject();  
        this.commit(request); 
        if (Utility.isEmpty(docSearchForm.getRootID()) && Utility.isEmpty(docSearchForm.getParentID())) {
          docSearchForm.setParentID(TextUtility.formatIntegerObj(docTep.getID()));
          docSearchForm.setRootID(TextUtility.formatIntegerObj(docTep.getRootID()));
        }
      }

      if ((Utility.isEmpty(docSearchForm.getRootID()) ||"null".equals(docSearchForm.getRootID())) && (Utility.isEmpty(docSearchForm.getParentID()) || "null".equals(docSearchForm.getParentID()))) {
        if (!Utility.isEmpty(publicRootList) && publicRootList.size()>0){
          DmsRoot folderRoot = (DmsRoot)publicRootList.get(0);
          DmsDocument folderRootDocument = docRetrievalManager.getRootFolderByRootID(folderRoot.getID());
          
          if(!GlobalConstant.OP_MODE_MY_FAVORITE.equals(docSearchForm.getIsMyFavorite())){
            // Retieve the root folder document object.
            documentRoot = docRetrievalManager.getRootFolderByRootID(folderRootDocument.getRootID());
            request.setAttribute("rootFolder", documentRoot);

            folderTreeList = docRetrievalManager.getFolderByParentIDRootID(folderRootDocument.getID(), folderRootDocument.getRootID());
            request.setAttribute("folderTreeList", folderTreeList);
            
            // Retrieve the location path of the folder.
            path = docRetrievalManager.getLocationPath(folderRootDocument.getParentID());
            request.setAttribute("location", path);
            docSearchForm.setRootID(folderRootDocument.getRootID().toString());
            docSearchForm.setParentID(folderRootDocument.getID().toString());
          }else{
            DmsDocument doc = docRetrievalManager.getMyFavoriteObject();    
            
            // Retieve the root folder document object.
            documentRoot = docRetrievalManager.getRootFolderByRootID(doc.getRootID());
            request.setAttribute("rootFolder", documentRoot);

            folderTreeList = docRetrievalManager.getFolderByParentIDRootID(doc.getID(), doc.getRootID());
            request.setAttribute("folderTreeList", folderTreeList);

            // Retrieve the location path of the folder.
            path = docRetrievalManager.getLocationPath(doc.getID());
            request.setAttribute("location", path);
            docSearchForm.setRootID(doc.getRootID().toString());
            docSearchForm.setParentID(doc.getID().toString());
          }
        }
      } else {
        // Retrieve the folder list for folder tree listing for current root ID.
        if (!Utility.isEmpty(docSearchForm.getRootID())) {
            
          if(!GlobalConstant.OP_MODE_MY_FAVORITE.equals(docSearchForm.getIsMyFavorite())){
            // Retieve the root folder document object.
            documentRoot = docRetrievalManager.getRootFolderByRootID(TextUtility.parseIntegerObj(docSearchForm.getRootID()));
            request.setAttribute("rootFolder", documentRoot);

            folderTreeList = docRetrievalManager.getFolderByParentIDRootID(documentRoot.getID(), TextUtility.parseIntegerObj(docSearchForm.getRootID()));
            request.setAttribute("folderTreeList", folderTreeList);
          }else{
            DmsDocument doc = docRetrievalManager.getMyFavoriteObject();          
          
            // Retieve the root folder document object.
            documentRoot = docRetrievalManager.getRootFolderByRootID(doc.getRootID());
            request.setAttribute("rootFolder", documentRoot);

            // Retrieve the folder list for folder tree listing.         
            folderTreeList.add(docRetrievalManager.getMyFavoriteObject());
            request.setAttribute("folderTreeList", folderTreeList);           
            
          }
        }
        if (!Utility.isEmpty(docSearchForm.getParentID())){
          //if(!GlobalConstant.OP_MODE_MY_FAVORITE.equals(docSearchForm.getIsMyFavorite())){
            // Retrieve the location path of the folder.
//            if ("M".equals(docSearchForm.getActionType())&&Utility.isEmpty(docSearchForm.getParentID())){
//              docSearchForm.setParentID(TextUtility.formatIntegerObj(docTep.getID())); 
//            }
          
            Integer parentID = TextUtility.parseIntegerObj(docSearchForm.getParentID());
            path = docRetrievalManager.getLocationPath(parentID);
            request.setAttribute("location", path);
         /* }else{
            DmsDocument doc = docRetrievalManager.getMyFavoriteObject(); 
             
            // Retrieve the location path of the folder.
            Integer parentID = doc.getID();
            path = docRetrievalManager.getLocationPath(parentID);
            request.setAttribute("location", path);
          }*/
        }
     }
      
      List resultList = new ArrayList();
      if (publicRootList.size() >0) {
      	if ("S".equals(docSearchForm.getActionType())){
      		List rootIDs = Utility.getPropertyList(publicRootList, "ID");
          if (!Utility.isEmpty(docSearchForm.getBasicSearchKeyword())) {
            docSearchForm.setDocumentType(DmsDocument.FOLDER_TYPE);
            resultList = docRetrievalManager.getDmsFolderListByDocumentTypeRootIDLists(docSearchForm, rootIDs);
          }
          request.setAttribute(this.m_sListName, resultList);
      	} else {
      		List rootIDs = new ArrayList();
      		if (!Utility.isEmpty(docSearchForm.getRootID()) && !"null".equals(docSearchForm.getRootID())){
      			rootIDs.add(TextUtility.parseIntegerObj(docSearchForm.getRootID()));
      		}
          docSearchForm.setDisplayOption(DmsDocument.FOLDER_TYPE);
      		super.getListData(mapping,form,request,response);
          docSearchForm.setDisplayOption(ListDmsDocumentForm.DEFAULT_DISPLAY_DOC_TYPE);
      	}
        
        if (documentRoot==null) {
          documentRoot = docRetrievalManager.getRootFolderByRootID(((DmsRoot)publicRootList.get(0)).getID());
          request.setAttribute("rootFolder", documentRoot);
        }
        if (Utility.isEmpty(folderTreeList)) {
          // Retrieve the folder list for folder tree listing.
          folderTreeList = docRetrievalManager.getFolderByParentIDRootID(documentRoot.getID(), ((DmsRoot)publicRootList.get(0)).getID());
          request.setAttribute("folderTreeList", folderTreeList);
        }
      } else {
        request.setAttribute(this.m_sListName, new ArrayList());
      }      
      
      if ("M".equals(docSearchForm.getActionType())){
        DmsDocument doc = docRetrievalManager.getMyFavoriteObject(); 
        List rootIDs = docRetrievalManager.getFolderByParentIDRootID(doc.getID(),doc.getRootID(), sortAttribute, sortOrder);
        request.setAttribute(this.m_sListName, rootIDs);
      } else if ("R".equals(docSearchForm.getActionType())){
      	if (!SystemParameterFactory.getSystemParameterBoolean(SystemParameterConstant.DMS_DISPLALY_NO_ACCESS_DOCUUMENT)){
      		List result = this.getAccessListData(docSearchForm,request);
      		request.setAttribute(this.m_sListName, result);
      	} else {
      		AuditTrailDAObject auditTrailDAO = new AuditTrailDAObject(sessionContainer,conn);
      		List result = auditTrailDAO.getListByDocumentTypeNew(docSearchForm);
      		request.setAttribute(this.m_sListName, result);
      	}
      }

      docValidateManager = new DocumentValidateManager(sessionContainer, conn);
      // check permission
      if (!"M".equals(docSearchForm.getActionType()) && !"R".equals(docSearchForm.getActionType()) && !"S".equals(docSearchForm.getActionType())){
      	boolean havePermission = docValidateManager.checkHasPermissionOnObject(GlobalConstant.OBJECT_TYPE_DOCUMENT, TextUtility.parseIntegerObj(docSearchForm.getParentID()), TextUtility.parseIntegerObj(docSearchForm.getRootID()), "I");
      }  
    } catch (ApplicationException appEx) {
    	request.setAttribute("location","");
      log.error(appEx, appEx);
      this.rollback(request);
      throw appEx;
    } catch (Exception e) {
      log.error(e, e);
      this.rollback(request);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
      conn = null;
      try { docRetrievalManager.release(); } catch (Exception ignore) {} finally { docRetrievalManager = null; }
      try { rootOperationManager.release(); } catch (Exception ignore) {} finally { rootOperationManager = null; }
      try { rootRetrievalManager.release(); } catch (Exception ignore) {} finally { rootRetrievalManager = null; }
      try { docValidateManager.release(); } catch (Exception ignore) {} finally { docValidateManager = null; }
    }
  }
}
